package com.senthink.gl.business.userlog;

import com.senthink.gl.business.common.entity.SearchRequest;
import com.senthink.gl.business.common.exception.DataAccessException;
import com.senthink.gl.business.domain.entity.User;
import com.senthink.gl.business.domain.entity.UserLog;
import com.senthink.gl.business.domain.entity.UserLog_;
import com.senthink.gl.business.domain.entity.User_;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;

/**
 * 操作日志DataService
 *
 * @author yuanpeng@senthink.com
 * @data 2018-01-30 9:45
 */

@Service
public class UserLogDataService {

    @Autowired
    private UserLogRepository repository;

    /**
     * 保存一条操作日志
     * @param userLog
     * @return
     */
    public UserLog save(UserLog userLog) {
        try {
            return repository.save(userLog);
        } catch (Exception e) {
            throw new DataAccessException(e);
        }
    }

    /**
     * 获取操作日志分页列表
     *
     * @param role          角色
     * @param operate       操作类型
     * @param startTime     开始时间
     * @param endTime       结束时间
     * @param searchRequest 模糊搜索值域
     * @param pageRequest   分页请求类
     * @return
     */
    public Page<UserLog> findAll(String role, String operate, Date startTime, Date endTime, SearchRequest searchRequest, PageRequest pageRequest) {
        try {
            return repository.findAll((root, query, cb) -> {
                List<Predicate> predicates = new LinkedList<>();
                if (StringUtils.isNoneBlank(role)) {
                    predicates.add(cb.equal(root.get(UserLog_.role), role));
                }
                if (StringUtils.isNoneBlank(operate)) {
                    predicates.add(cb.equal(root.get(UserLog_.operate), operate));
                }
                predicates.add(cb.between((root.get(UserLog_.createTime)), startTime, endTime));
                if (StringUtils.isNoneBlank(searchRequest.getSearch())) {
                    Root<User> userRoot = query.from(User.class);
                    Predicate p1 = cb.gt(cb.locate(root.get(UserLog_.details), searchRequest.getSearch()), 0);
                    Predicate p2 = cb.gt(cb.locate(userRoot.get(User_.name), searchRequest.getSearch()), 0);
                    Predicate p3 = cb.equal(root.get(UserLog_.uid), userRoot.get(User_.uid));
                    predicates.add(cb.or(p1, (cb.and(p2, p3))));
                }
                return cb.and(predicates.toArray(new Predicate[predicates.size()]));
            }, pageRequest);
        } catch (Exception e) {
            throw new DataAccessException(e);
        }
    }

    /**
     *  获取该用户上一个操作记录
     * @param uid
     * @param operate
     * @param ip
     * @return
     */
    public Optional<UserLog> findTopByUidAndOperateAndIpOrderByCreateTimeDesc(String uid, String operate, String ip) {
        try {
            return repository.findTopByUidAndOperateAndIpOrderByCreateTimeDesc(uid, operate, ip);
        } catch (Exception e) {
            throw new DataAccessException(e);
        }
    }

    /**
     * 删除日志
     * @param userLog
     */
    public void delete(UserLog userLog) {
        try {
            repository.delete(userLog);
        } catch (Exception e) {
            throw new DataAccessException(e);
        }
    }
}
